using Dapper;
using MediatR;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.SalesManagement.H;
using System.Data;
using static RBAC.ErrorCode.APIEnums;
using System;

namespace RBAC.Write.Api.Application.Handler.ERP.SalesManagement
{
    /// <summary>
    /// 编辑（修改）发货通知单处理器
    /// </summary>
    public class UpdateDeliveryNoticeHandler : IRequestHandler<UpdateDeliveryNoticeCommand, APIResult<bool>>
    {
        private readonly IDbConnectionFactory _dbConnectionFactory;

        public UpdateDeliveryNoticeHandler(IDbConnectionFactory dbConnectionFactory)
        {
            _dbConnectionFactory = dbConnectionFactory;
        }

        public async Task<APIResult<bool>> Handle(UpdateDeliveryNoticeCommand request, CancellationToken cancellationToken)
        {
            IDbConnection? conn = null;
            IDbTransaction? tran = null;

            try
            {
                conn = _dbConnectionFactory.CreateConnection();
                tran = conn.BeginTransaction();

                // 1) 校验主表是否存在、未删除
                var exists = await conn.ExecuteScalarAsync<int>(
                    "SELECT COUNT(1) FROM Delivery_notice WHERE Id=@Id AND IsDeleted=0",
                    new { Id = request.Id }, tran);

                if (exists <= 0)
                {
                    tran.Rollback();
                    return new APIResult<bool> { Code = Error, Msg = "单据不存在或已删除", Data = false };
                }

                // 1.1) 仅开立状态(Status=0)可编辑
                var status = await conn.ExecuteScalarAsync<int>(
                    "SELECT Status FROM Delivery_notice WHERE Id=@Id AND IsDeleted=0 LIMIT 1",
                    new { Id = request.Id }, tran);
                if (status != 0)
                {
                    tran.Rollback();
                    return new APIResult<bool> { Code = Error, Msg = "仅开立状态可编辑", Data = false };
                }

                // 2) 更新主表（不变更 Bill_code / Bill_date / Status）
                var affectHeader = await conn.ExecuteAsync(@"
UPDATE Delivery_notice
SET Biz_type = @BizType,
    Sales_order_code = @SalesOrderCode,
    Customer_id = @CustomerId,
    Salesman_id = @SalesmanId,
    Warehouse_id = @WarehouseId,
    Receiver = @Receiver,
    Phone = @Phone,
    Address = @Address,
    Delivery_date = @DeliveryDate,
    Remark = @Remark,
    Freight = @Freight,
    Loading_fee = @LoadingFee
WHERE Id = @Id AND IsDeleted = 0", new
                {
                    request.BizType,
                    request.SalesOrderCode,
                    request.CustomerId,
                    request.SalesmanId,
                    request.WarehouseId,
                    request.Receiver,
                    request.Phone,
                    request.Address,
                    request.DeliveryDate,
                    request.Remark,
                    request.Freight,
                    request.LoadingFee,
                    request.Id
                }, tran);

                if (affectHeader <= 0)
                {
                    tran.Rollback();
                    return new APIResult<bool> { Code = Error, Msg = "更新主表失败", Data = false };
                }

                // 3) 明细整体替换：先逻辑删除旧明细，再插入新明细
                await conn.ExecuteAsync(
                    "UPDATE Delivery_notice_item SET IsDeleted = 1 WHERE Delivery_notice_id = @Id AND IsDeleted = 0",
                    new { Id = request.Id }, tran);

                if (request.Items != null && request.Items.Count > 0)
                {
                    var insertSql = @"
INSERT INTO Delivery_notice_item(
    Delivery_notice_id, Material_id, Material_code, Material_name,
    Unit, Qty, Package_qty, Batch_no, Remark,
    CreateTime, CreateUser, IsDeleted)
VALUES(
    @DeliveryNoticeId, @MaterialId, @MaterialCode, @MaterialName,
    @Unit, @Qty, @PackageQty, @BatchNo, @Remark,
    @CreateTime, @CreateUser, @IsDeleted)";

                    foreach (var item in request.Items)
                    {
                        var p = new
                        {
                            DeliveryNoticeId = request.Id,
                            MaterialId = item.MaterialId,
                            MaterialCode = item.MaterialCode,
                            MaterialName = item.MaterialName,
                            Unit = item.Unit,
                            Qty = item.Qty,
                            PackageQty = item.PackageQty,
                            BatchNo = item.BatchNo,
                            Remark = item.Remark,
                            CreateTime = DateTime.Now,
                            CreateUser = "当前登录人",
                            IsDeleted = false
                        };
                        await conn.ExecuteAsync(insertSql, p, tran);
                    }
                }

                tran.Commit();
                return new APIResult<bool> { Code = Success, Msg = "更新成功", Data = true };
            }
            catch (Exception ex)
            {
                try { tran?.Rollback(); } catch { }
                return new APIResult<bool> { Code = Error, Msg = $"更新异常: {ex.Message}", Data = false };
            }
            finally
            {
                try { tran?.Dispose(); } catch { }
                try { conn?.Dispose(); } catch { }
            }
        }
    }
}
